/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package a1;

import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author Azka Devara
 */
public class Grid {

    private char grid[][];
    private ProjectModel pm;
    private ArrayList<Car> carArray;
    private trafficLight tr;
    private int i = 0;

    /** Grid Constructor*/
    public Grid(ProjectModel pm) {
        this.pm = pm;
        int gridSize = pm.getGridSize();
        grid = new char[gridSize][gridSize];
        carArray = new ArrayList<Car>();
        tr = new trafficLight();



    }//end of constructor

    /** Filling the grid with char '.' */
    public void setGridChar() {
        //Displays grid
        char fill = '.';
        for (int h = 0; h < 26; h++) {
            char[] rows = grid[h];
            rows[h] = fill;
            for (int v = 0; v < 25; v++) {
                rows[v] = fill;
            }
        }
    } //end of method

    /** Build and show horizontal and vertical lanes*/
    public void buildLanes() {
        setGridChar();
        verStripes(pm.getVer());
        horStripes(pm.getHor());
        buildHor(pm.getHor());
        buildVer(pm.getVer());
        showGrid();
    }

    public void runCycle(ProjectModel model, int round) {
        pm.setCycle(round);
        int counter = pm.getCycle();

        for (; i < counter; i = i + 1) {

            buildHorCars(model.getHorProb(), model.getHor());
            buildVerCars(model.getVerProb(), model.getVer());
            tr.trafficShuffle(i);
            trafficControl();
            showGrid();
            System.out.println(" ");


        }
    }//end method

    public void showGrid() {
        //Displays grid
        for (int r = 0; r < 26; r++) {
            char[] rows = grid[r];
            for (int c = 0; c < 25; c++) {
                System.out.print(grid[r][c]);
            }
            System.out.println("");
        }
    }

    /** setting up the horizontal lanes*/
    public void buildHor(int horNum) {
        int count = 0;
        int middle = 26 / 2;
        while (count != horNum) {
            for (int r = 0; r < 26; r++) {
                char[] rows = grid[r];
                for (int c = 0; c < 25; c++) {
                    if (r == middle) {
                        rows[c] = ' ';
                    }
                }
            }
            count += 1;
            middle -= 1;
        }
    }

    /** setting up the vertical lanes*/
    public void buildVer(int verNum) {
        int count = 0;
        int middle = 26 / 2;
        while (count != verNum) {
            for (int r = 0; r < 26; r++) {
                char[] rows = grid[r];
                for (int c = 0; c < 25; c++) {
                    if (c == middle) {
                        rows[c] = ' ';
                    }
                }
            }
            count += 1;
            if (count != 3) {
                middle -= 1;
            }
            if (count == 3) {
                middle += 3;
            }
        }
    }

    /** setting up the horizontal stripes '|'*/
    public void verStripes(int verLanes) {

        int lowerBound = 26 / 2 - verLanes;
        int upperBound = 26 / 2 + verLanes / 2;

        if (verLanes == 1) {
            upperBound = 26 / 2 + verLanes;
        }
        if (verLanes == 4) {
            lowerBound += 1;
        }

        for (int r = 0; r < 26; r++) {
            char[] rows = grid[r];
            for (int c = 0; c < 25; c++) {
                if (c == lowerBound) {
                    rows[c] = '|';
                }
                if (c == upperBound) {
                    rows[c] = '|';
                }

            }
        }
    }

    /** setting up the horizontal stripes '-'*/
    public void horStripes(int horLanes) {

        int upperBound = 26 / 2 - horLanes;
        int lowerBound = 26 / 2 + horLanes / 2;

        if (horLanes == 1) {
            lowerBound = 26 / 2 + horLanes;
        }

        for (int r = 0; r < 26; r++) {
            char[] rows = grid[r];
            for (int c = 0; c < 25; c++) {
                if (r == upperBound) {
                    rows[c] = '-';
                }
                if (r == lowerBound) {
                    rows[c] = '-';
                }
            }
        }
    }

    /** setting up the horizontal Cars*/
    public void buildHorCars(double horProb, int horLanes) {

        Random rnd = new Random();
        float x = rnd.nextFloat();

        if (horProb >= x) {
            if (horLanes == 1) {
                carArray.add(new Car(13, 0, 'r'));
            }
            if (horLanes == 2) {
                carArray.add(new Car((12 + (int) (Math.random() * 2)), 0, 'r'));
            }
            if (horLanes == 3) {
                carArray.add(new Car((11 + (int) (Math.random() * 3)), 0, 'r'));
            }


        }//end if
    }

    /** setting up the vertical Cars*/
    public void buildVerCars(double verProb, int verLanes) {

        Random rnd = new Random();
        float x = rnd.nextFloat();
        if (verProb >= x) {
            if (verLanes == 1) {
                carArray.add(new Car(0, 13, 'd'));
            }
            if (verLanes == 2) {
                carArray.add(new Car(0, (12 + (int) (Math.random() * 2)), 'd'));
            }
            if (verLanes == 3) {
                carArray.add(new Car(0, (11 + (int) (Math.random() * 3)), 'd'));
            }
            if (verLanes == 4) {
                carArray.add(new Car(0, (11 + (int) (Math.random() * 4)), 'd'));
            }


        }//end if
    }//end of method

    /**insert cars to grid*/
    public void insertCars() {
        for (int x = 0; x < carArray.size(); x = x + 1) {
            int insertx = carArray.get(x).getXcor();
            int inserty = carArray.get(x).getyCor();
            grid[insertx][inserty] = 'c';
        }
    }

    /**move the cars accordingly to traffic light situation*/
    public void trafficControl() {


        for (int count = 0; count < carArray.size(); count = count + 1) {


            if (carArray.get(count).getDirection() == 'd') {
                if (tr.getVerRed() == true) {
                    grid[9][9] = 'R';
                    if (carArray.get(count).getXcor() < 10) {
                        eraseTrails(count);
                        moveHor(count);
                    }
                    if (carArray.get(count).getXcor() > 10) {
                        eraseTrails(count);
                        moveHor(count);
                    }

                } else if (tr.getVerRed() == false) {
                    grid[9][9] = 'G';
                    eraseTrails(count);
                    moveHor(count);
                }


            }//end if direction 'd'

            if (carArray.get(count).getDirection() == 'r') {
                if (tr.getHorRed() == true) {

                    grid[15][8] = 'R';
                    if (carArray.get(count).getyCor() < 10) {
                        eraseTrails(count);
                        moveVer(count);
                    }
                    if (carArray.get(count).getyCor() > 10) {
                        eraseTrails(count);
                        moveVer(count);
                    }

                } else if (tr.getHorRed() == false) {

                    grid[15][8] = 'G';
                    eraseTrails(count);
                    moveVer(count);
                }

            }//end if direction r

        }//end for


    }//end method

    /** Move Horizontal cars*/
    public void moveHor(int cycle2) {
        carArray.get(cycle2).setXcor((carArray.get(cycle2).getXcor()) + 1); //add x coordinate 1 step

        int x = carArray.get(cycle2).getXcor();
        int y = carArray.get(cycle2).getyCor();
        if (x > 25) {
            carArray.remove(cycle2);
        } else {
            grid[x][y] = 'c';
        }
    }

    /** Move Vertical cars*/
    public void moveVer(int cycle3) {
        carArray.get(cycle3).setYcor((carArray.get(cycle3).getyCor()) + 1); // add y coordinate 1 step
        int x2 = carArray.get(cycle3).getXcor();
        int y2 = carArray.get(cycle3).getyCor();
        if (y2 > 35) {
            carArray.remove(cycle3);
        } else {
            grid[x2][y2] = 'c';
        }
    }

    /** Delete cars trails*/
    public void eraseTrails(int cntr) {
        int originalX = carArray.get(cntr).getXcor();
        int originalY = carArray.get(cntr).getyCor();
        grid[originalX][originalY] = ' '; //erase car trail
    }
}
